package evolution.visualization;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import evolution.individual.Individual;
import evolution.problem.OptimizationProblem;
import evolution.problem.ProblemConstraints;

public class FunctionAsMapChart {

	public static void createFunctionAsMapChart(
			OptimizationProblem optimizationProblem, Individual[][] populations)
			throws IOException {

		String datFile = DataFileBuilder.createGnuplotDataFile(populations);
		datFile = "'" + datFile + "'";
		String function = optimizationProblem.getGnuplotFunction();
		String functionName = optimizationProblem.getGnuplotFunctionName();
		ProblemConstraints constraints = optimizationProblem.getConstraints();
		double minArg = constraints.getMinArg();
		double maxArg = constraints.getMaxArg();
		String constraint = convertConstraintToGnuplotFormat(minArg, maxArg);

		List<String> command = new ArrayList<String>();
		String gnuplotExecutable = getGnuplotExecutable();
		if (gnuplotExecutable != null) {
			command.add(gnuplotExecutable);
			command.add("-p");
			command.add("-e");

			String gnuplotCmd = "set isosamples 100; " + functionName
					+ "(x,y) = " + function + "; splot " + constraint + " "
					+ functionName + "(x,y) with pm3d, " + datFile
					+ " title 'Znalezione rozwiązania' pt 7" + "; exit;";

			command.add(gnuplotCmd);
			ProcessBuilder gnuplotProcess = new ProcessBuilder(command);
			try {
				gnuplotProcess.start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private static String convertConstraintToGnuplotFormat(double minArg,
			double maxArg) {
		return "[" + minArg + ":" + maxArg + "]" + " [" + minArg + ":" + maxArg
				+ "]";
	}

	public static String getGnuplotExecutable() {
		String systemName = System.getProperty("os.name");
		if (systemName.startsWith("Windows")) {
			String exe64 = "C:/Program Files (x86)/gnuplot/bin/wgnuplot.exe";
			String exe32 = "C:/Program Files/gnuplot/bin/wgnuplot.exe";

			if (new File(exe64).isFile()) {
				return exe64;
			} else if (new File(exe32).isFile()) {
				return exe32;
			}
			return null;
		} else {
			return "gnuplot";
		}
	}
}
